home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / quake.zip / HIPGRAPL.ZIP / ITEMS.QC < prev    next >
Text File  |  1997-04-09  |  31KB  |  1,429 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.  
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then
  102. rot you down to your maximum health limit,
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.  
  155.     if (other.classname != "player")
  156.         return;
  157.  
  158.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  159.     {
  160.         if (other.health >= 250)
  161.             return;
  162.         if (!T_Heal(other, self.healamount, 1))
  163.             return;
  164.     }
  165.     else
  166.     {
  167.         if (!T_Heal(other, self.healamount, 0))
  168.             return;
  169.     }
  170.  
  171.     sprint(other, "You receive ");
  172.     s = ftos(self.healamount);
  173.     sprint(other, s);
  174.     sprint(other, " health\n");
  175.  
  176. // health touch sound
  177.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  178.  
  179.     stuffcmd (other, "bf\n");
  180.  
  181.     self.model = string_null;
  182.     self.solid = SOLID_NOT;
  183.  
  184.     // Megahealth = rot down the player's super health
  185.     if (self.healtype == 2)
  186.     {
  187. // 11/02/96 removed SUPERHEALTH from defs.qc
  188. //      other.items = other.items | IT_SUPERHEALTH;
  189.         self.nextthink = time + 5;
  190.         self.think = item_megahealth_rot;
  191.         self.owner = other;
  192.     }
  193.     else
  194.     {
  195.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  196.         {
  197.             if (deathmatch)
  198.                 self.nextthink = time + 20;
  199.             self.think = SUB_regen;
  200.         }
  201.     }
  202.  
  203.     activator = other;
  204.     SUB_UseTargets();                // fire all targets / killtargets
  205. };
  206.  
  207. void() item_megahealth_rot =
  208. {
  209.     other = self.owner;
  210.  
  211.     if (other.health > other.max_health)
  212.     {
  213.         other.health = other.health - 1;
  214.         self.nextthink = time + 1;
  215.         return;
  216.     }
  217.  
  218. // it is possible for a player to die and respawn between rots, so don't
  219. // just blindly subtract the flag off
  220. // MED 11/02/96 removed SUPERHEALTH
  221. //   other.items = other.items - (other.items & IT_SUPERHEALTH);
  222.  
  223.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  224.     {
  225.         self.nextthink = time + 20;
  226.         self.think = SUB_regen;
  227.     }
  228. };
  229.  
  230. /*
  231. ===============================================================================
  232.  
  233. ARMOR
  234.  
  235. ===============================================================================
  236. */
  237.  
  238. void() armor_touch;
  239.  
  240. void() armor_touch =
  241. {
  242.     local    float    type, value, bit;
  243.  
  244.     if (other.health <= 0)
  245.         return;
  246.     if (other.classname != "player")
  247.         return;
  248.  
  249.     if (self.classname == "item_armor1")
  250.     {
  251.         type = 0.3;
  252.         value = 100;
  253.       bit = IT_ARMOR1;
  254.    }
  255.     if (self.classname == "item_armor2")
  256.     {
  257.         type = 0.6;
  258.         value = 150;
  259.         bit = IT_ARMOR2;
  260.     }
  261.     if (self.classname == "item_armorInv")
  262.     {
  263.         type = 0.8;
  264.         value = 200;
  265.         bit = IT_ARMOR3;
  266.     }
  267.     if (other.armortype*other.armorvalue >= type*value)
  268.         return;
  269.  
  270.     other.armortype = type;
  271.     other.armorvalue = value;
  272.    other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  273.  
  274.     self.solid = SOLID_NOT;
  275.     self.model = string_null;
  276.     if (deathmatch == 1)
  277.         self.nextthink = time + 20;
  278.     self.think = SUB_regen;
  279.  
  280.     sprint(other, "You got armor\n");
  281. // armor touch sound
  282.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  283.     stuffcmd (other, "bf\n");
  284.  
  285.     activator = other;
  286.     SUB_UseTargets();                // fire all targets / killtargets
  287. };
  288.  
  289.  
  290. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  291. */
  292.  
  293. void() item_armor1 =
  294. {
  295.     self.touch = armor_touch;
  296.     precache_model ("progs/armor.mdl");
  297.     setmodel (self, "progs/armor.mdl");
  298.     self.skin = 0;
  299.     setsize (self, '-16 -16 0', '16 16 56');
  300.     StartItem ();
  301. };
  302.  
  303. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  304. */
  305.  
  306. void() item_armor2 =
  307. {
  308.     self.touch = armor_touch;
  309.     precache_model ("progs/armor.mdl");
  310.     setmodel (self, "progs/armor.mdl");
  311.     self.skin = 1;
  312.     setsize (self, '-16 -16 0', '16 16 56');
  313.     StartItem ();
  314. };
  315.  
  316. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  317. */
  318.  
  319. void() item_armorInv =
  320. {
  321.     self.touch = armor_touch;
  322.     precache_model ("progs/armor.mdl");
  323.     setmodel (self, "progs/armor.mdl");
  324.     self.skin = 2;
  325.     setsize (self, '-16 -16 0', '16 16 56');
  326.     StartItem ();
  327. };
  328.  
  329. /*
  330. ===============================================================================
  331.  
  332. WEAPONS
  333.  
  334. ===============================================================================
  335. */
  336.  
  337. void() bound_other_ammo =
  338. {
  339.     if (other.ammo_shells > 100)
  340.         other.ammo_shells = 100;
  341.     if (other.ammo_nails > 200)
  342.         other.ammo_nails = 200;
  343.     if (other.ammo_rockets > 100)
  344.         other.ammo_rockets = 100;
  345.     if (other.ammo_cells > 100)
  346.         other.ammo_cells = 100;
  347. };
  348.  
  349.  
  350. //MED 01/06/97 added hipnotic weapons into rankings
  351. float(float w) RankForWeapon =
  352. {
  353.     if (w == IT_LIGHTNING)
  354.         return 1;
  355.     if (w == IT_ROCKET_LAUNCHER)
  356.         return 2;
  357.    if (w == IT_LASER_CANNON)
  358.         return 3;
  359.    if (w == IT_SUPER_NAILGUN)
  360.       return 4;
  361.    if (w == IT_PROXIMITY_GUN)
  362.       return 5;
  363.    if (w == IT_GRENADE_LAUNCHER)
  364.       return 6;
  365.    if (w == IT_SUPER_SHOTGUN)
  366.       return 7;
  367.     if (w == IT_NAILGUN)
  368.       return 8;
  369.    if (w == IT_MJOLNIR)
  370.       return 9;
  371.    return 10;
  372. };
  373.  
  374. /*
  375. =============
  376. Deathmatch_Weapon
  377.  
  378. Deathmatch weapon change rules for picking up a weapon
  379.  
  380. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  381. =============
  382. */
  383. void(float old, float new) Deathmatch_Weapon =
  384. {
  385.     local float or, nr;
  386.  
  387. // change self.weapon if desired
  388.     or = RankForWeapon (self.weapon);
  389.     nr = RankForWeapon (new);
  390.     if ( nr < or )
  391.         self.weapon = new;
  392. };
  393.  
  394. /*
  395. =============
  396. weapon_touch
  397. =============
  398. */
  399. float() W_BestWeapon;
  400.  
  401. void() weapon_touch =
  402. {
  403.     local    float    hadammo, best, new, old;
  404.     local    entity    stemp;
  405.     local    float    leave;
  406.  
  407.     if (!(other.flags & FL_CLIENT))
  408.         return;
  409.  
  410. // if the player was using his best weapon, change up to the new one if better
  411.     stemp = self;
  412.     self = other;
  413.     best = W_BestWeapon();
  414.     self = stemp;
  415.  
  416.     if (deathmatch == 2 || coop)
  417.         leave = 1;
  418.     else
  419.         leave = 0;
  420.  
  421.     if (self.classname == "weapon_nailgun")
  422.     {
  423.         if (leave && (other.items & IT_NAILGUN) )
  424.             return;
  425.         hadammo = other.ammo_nails;
  426.         new = IT_NAILGUN;
  427.         other.ammo_nails = other.ammo_nails + 30;
  428.     }
  429.     else if (self.classname == "weapon_supernailgun")
  430.     {
  431.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  432.             return;
  433.         hadammo = other.ammo_rockets;
  434.         new = IT_SUPER_NAILGUN;
  435.         other.ammo_nails = other.ammo_nails + 30;
  436.     }
  437.     else if (self.classname == "weapon_supershotgun")
  438.     {
  439.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  440.             return;
  441.         hadammo = other.ammo_rockets;
  442.         new = IT_SUPER_SHOTGUN;
  443.         other.ammo_shells = other.ammo_shells + 5;
  444.     }
  445.     else if (self.classname == "weapon_rocketlauncher")
  446.     {
  447.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  448.             return;
  449.         hadammo = other.ammo_rockets;
  450.         new = IT_ROCKET_LAUNCHER;
  451.         other.ammo_rockets = other.ammo_rockets + 5;
  452.     }
  453.     else if (self.classname == "weapon_grenadelauncher")
  454.     {
  455.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  456.             return;
  457.         hadammo = other.ammo_rockets;
  458.         new = IT_GRENADE_LAUNCHER;
  459.         other.ammo_rockets = other.ammo_rockets + 5;
  460.     }
  461.     else if (self.classname == "weapon_lightning")
  462.     {
  463.         if (leave && (other.items & IT_LIGHTNING) )
  464.             return;
  465.         hadammo = other.ammo_rockets;
  466.         new = IT_LIGHTNING;
  467.         other.ammo_cells = other.ammo_cells + 15;
  468.     }
  469. //MED
  470.    else if (self.classname == "weapon_laser_gun")
  471.     {
  472.       if (leave && (other.items & IT_LASER_CANNON) )
  473.             return;
  474.         hadammo = other.ammo_rockets;
  475.       new = IT_LASER_CANNON;
  476.       other.ammo_cells = other.ammo_cells + 30;
  477.     }
  478. //MED
  479.    else if (self.classname == "weapon_mjolnir")
  480.     {
  481.       if (leave && (other.items & IT_MJOLNIR) )
  482.             return;
  483.         hadammo = other.ammo_rockets;
  484.       new = IT_MJOLNIR;
  485.       other.ammo_cells = other.ammo_cells + 30;
  486.     }
  487. //MED
  488.    else if (self.classname == "weapon_proximity_gun")
  489.     {
  490.       if (leave && (other.items & IT_PROXIMITY_GUN) )
  491.             return;
  492.         hadammo = other.ammo_rockets;
  493.       new = IT_PROXIMITY_GUN;
  494.       other.ammo_rockets = other.ammo_rockets + 6;
  495.     }
  496.    else
  497.         objerror ("weapon_touch: unknown classname");
  498.  
  499.     sprint (other, "You got the ");
  500.     sprint (other, self.netname);
  501.     sprint (other, "\n");
  502. // weapon touch sound
  503.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  504.     stuffcmd (other, "bf\n");
  505.  
  506.     bound_other_ammo ();
  507.  
  508. // change to the weapon
  509.     old = other.items;
  510.     other.items = other.items | new;
  511.  
  512.     stemp = self;
  513.     self = other;
  514.  
  515.     if (!deathmatch)
  516.         self.weapon = new;
  517.     else
  518.         Deathmatch_Weapon (old, new);
  519.  
  520.     W_SetCurrentAmmo();
  521.  
  522.     self = stemp;
  523.  
  524.     if (leave)
  525.         return;
  526.  
  527. // remove it in single player, or setup for respawning in deathmatch
  528.     self.model = string_null;
  529.     self.solid = SOLID_NOT;
  530.     if (deathmatch == 1)
  531.         self.nextthink = time + 30;
  532.     self.think = SUB_regen;
  533.  
  534.     activator = other;
  535.     SUB_UseTargets();                // fire all targets / killtargets
  536. };
  537.  
  538.  
  539. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  540. */
  541.  
  542. void() weapon_supershotgun =
  543. {
  544.     precache_model ("progs/g_shot.mdl");
  545.     setmodel (self, "progs/g_shot.mdl");
  546.     self.weapon = IT_SUPER_SHOTGUN;
  547.     self.netname = "Double-barrelled Shotgun";
  548.     self.touch = weapon_touch;
  549.     setsize (self, '-16 -16 0', '16 16 56');
  550.     StartItem ();
  551. };
  552.  
  553. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  554. */
  555.  
  556. void() weapon_nailgun =
  557. {
  558.     precache_model ("progs/g_nail.mdl");
  559.     setmodel (self, "progs/g_nail.mdl");
  560.     self.weapon = IT_NAILGUN;
  561.     self.netname = "nailgun";
  562.     self.touch = weapon_touch;
  563.     setsize (self, '-16 -16 0', '16 16 56');
  564.     StartItem ();
  565. };
  566.  
  567. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  568. */
  569.  
  570. void() weapon_supernailgun =
  571. {
  572.     precache_model ("progs/g_nail2.mdl");
  573.     setmodel (self, "progs/g_nail2.mdl");
  574.     self.weapon = IT_SUPER_NAILGUN;
  575.     self.netname = "Super Nailgun";
  576.     self.touch = weapon_touch;
  577.     setsize (self, '-16 -16 0', '16 16 56');
  578.     StartItem ();
  579. };
  580.  
  581. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  582. */
  583.  
  584. void() weapon_grenadelauncher =
  585. {
  586.     precache_model ("progs/g_rock.mdl");
  587.     setmodel (self, "progs/g_rock.mdl");
  588.     self.weapon = 3;
  589.     self.netname = "Grenade Launcher";
  590.     self.touch = weapon_touch;
  591.     setsize (self, '-16 -16 0', '16 16 56');
  592.     StartItem ();
  593. };
  594.  
  595. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  596. */
  597.  
  598. void() weapon_rocketlauncher =
  599. {
  600.     precache_model ("progs/g_rock2.mdl");
  601.     setmodel (self, "progs/g_rock2.mdl");
  602.     self.weapon = 3;
  603.     self.netname = "Rocket Launcher";
  604.     self.touch = weapon_touch;
  605.     setsize (self, '-16 -16 0', '16 16 56');
  606.     StartItem ();
  607. };
  608.  
  609.  
  610. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  611. */
  612.  
  613. void() weapon_lightning =
  614. {
  615.     precache_model ("progs/g_light.mdl");
  616.     setmodel (self, "progs/g_light.mdl");
  617.     self.weapon = 3;
  618.     self.netname = "Thunderbolt";
  619.     self.touch = weapon_touch;
  620.     setsize (self, '-16 -16 0', '16 16 56');
  621.     StartItem ();
  622. };
  623.  
  624.  
  625. /*
  626. ===============================================================================
  627.  
  628. AMMO
  629.  
  630. ===============================================================================
  631. */
  632.  
  633. void() ammo_touch =
  634. {
  635. local entity    stemp;
  636. local float        best;
  637.  
  638.     if (other.classname != "player")
  639.         return;
  640.     if (other.health <= 0)
  641.         return;
  642.  
  643. // if the player was using his best weapon, change up to the new one if better
  644.     stemp = self;
  645.     self = other;
  646.     best = W_BestWeapon();
  647.     self = stemp;
  648.  
  649.  
  650. // shotgun
  651.     if (self.weapon == 1)
  652.     {
  653.         if (other.ammo_shells >= 100)
  654.             return;
  655.         other.ammo_shells = other.ammo_shells + self.aflag;
  656.     }
  657.  
  658. // spikes
  659.     if (self.weapon == 2)
  660.     {
  661.         if (other.ammo_nails >= 200)
  662.             return;
  663.         other.ammo_nails = other.ammo_nails + self.aflag;
  664.     }
  665.  
  666. //    rockets
  667.     if (self.weapon == 3)
  668.     {
  669.         if (other.ammo_rockets >= 100)
  670.             return;
  671.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  672.     }
  673.  
  674. //    cells
  675.     if (self.weapon == 4)
  676.     {
  677.         if (other.ammo_cells >= 100)
  678.             return;
  679.         other.ammo_cells = other.ammo_cells + self.aflag;
  680.     }
  681.  
  682.     bound_other_ammo ();
  683.  
  684.     sprint (other, "You got the ");
  685.     sprint (other, self.netname);
  686.     sprint (other, "\n");
  687. // ammo touch sound
  688.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  689.     stuffcmd (other, "bf\n");
  690.  
  691. // change to a better weapon if appropriate
  692.  
  693.     if ( other.weapon == best )
  694.     {
  695.         stemp = self;
  696.         self = other;
  697.         self.weapon = W_BestWeapon();
  698.         W_SetCurrentAmmo ();
  699.         self = stemp;
  700.     }
  701.  
  702. // if changed current ammo, update it
  703.     stemp = self;
  704.     self = other;
  705.     W_SetCurrentAmmo();
  706.     self = stemp;
  707.  
  708. // remove it in single player, or setup for respawning in deathmatch
  709.     self.model = string_null;
  710.     self.solid = SOLID_NOT;
  711.     if (deathmatch == 1)
  712.         self.nextthink = time + 30;
  713.     self.think = SUB_regen;
  714.  
  715.     activator = other;
  716.     SUB_UseTargets();                // fire all targets / killtargets
  717. };
  718.  
  719.  
  720.  
  721.  
  722. float WEAPON_BIG2 = 1;
  723.  
  724. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  725. */
  726.  
  727. void() item_shells =
  728. {
  729.     self.touch = ammo_touch;
  730.  
  731.     if (self.spawnflags & WEAPON_BIG2)
  732.     {
  733.         precache_model ("maps/b_shell1.bsp");
  734.         setmodel (self, "maps/b_shell1.bsp");
  735.         self.aflag = 40;
  736.     }
  737.     else
  738.     {
  739.         precache_model ("maps/b_shell0.bsp");
  740.         setmodel (self, "maps/b_shell0.bsp");
  741.         self.aflag = 20;
  742.     }
  743.     self.weapon = 1;
  744.     self.netname = "shells";
  745.     setsize (self, '0 0 0', '32 32 56');
  746.     StartItem ();
  747. };
  748.  
  749. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  750. */
  751.  
  752. void() item_spikes =
  753. {
  754.     self.touch = ammo_touch;
  755.  
  756.     if (self.spawnflags & WEAPON_BIG2)
  757.     {
  758.         precache_model ("maps/b_nail1.bsp");
  759.         setmodel (self, "maps/b_nail1.bsp");
  760.         self.aflag = 50;
  761.     }
  762.     else
  763.     {
  764.         precache_model ("maps/b_nail0.bsp");
  765.         setmodel (self, "maps/b_nail0.bsp");
  766.         self.aflag = 25;
  767.     }
  768.     self.weapon = 2;
  769.     self.netname = "nails";
  770.     setsize (self, '0 0 0', '32 32 56');
  771.     StartItem ();
  772. };
  773.  
  774. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  775. */
  776.  
  777. void() item_rockets =
  778. {
  779.     self.touch = ammo_touch;
  780.  
  781.     if (self.spawnflags & WEAPON_BIG2)
  782.     {
  783.         precache_model ("maps/b_rock1.bsp");
  784.         setmodel (self, "maps/b_rock1.bsp");
  785.         self.aflag = 10;
  786.     }
  787.     else
  788.     {
  789.         precache_model ("maps/b_rock0.bsp");
  790.         setmodel (self, "maps/b_rock0.bsp");
  791.         self.aflag = 5;
  792.     }
  793.     self.weapon = 3;
  794.     self.netname = "rockets";
  795.     setsize (self, '0 0 0', '32 32 56');
  796.     StartItem ();
  797. };
  798.  
  799.  
  800. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  801. */
  802.  
  803. void() item_cells =
  804. {
  805.     self.touch = ammo_touch;
  806.  
  807.     if (self.spawnflags & WEAPON_BIG2)
  808.     {
  809.         precache_model ("maps/b_batt1.bsp");
  810.         setmodel (self, "maps/b_batt1.bsp");
  811.         self.aflag = 12;
  812.     }
  813.     else
  814.     {
  815.         precache_model ("maps/b_batt0.bsp");
  816.         setmodel (self, "maps/b_batt0.bsp");
  817.         self.aflag = 6;
  818.     }
  819.     self.weapon = 4;
  820.     self.netname = "cells";
  821.     setsize (self, '0 0 0', '32 32 56');
  822.     StartItem ();
  823. };
  824.  
  825.  
  826. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  827. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  828. */
  829.  
  830. float WEAPON_SHOTGUN = 1;
  831. float WEAPON_ROCKET = 2;
  832. float WEAPON_SPIKES = 4;
  833. float WEAPON_BIG = 8;
  834. void() item_weapon =
  835. {
  836.     self.touch = ammo_touch;
  837.  
  838.     if (self.spawnflags & WEAPON_SHOTGUN)
  839.     {
  840.         if (self.spawnflags & WEAPON_BIG)
  841.         {
  842.             precache_model ("maps/b_shell1.bsp");
  843.             setmodel (self, "maps/b_shell1.bsp");
  844.             self.aflag = 40;
  845.         }
  846.         else
  847.         {
  848.             precache_model ("maps/b_shell0.bsp");
  849.             setmodel (self, "maps/b_shell0.bsp");
  850.             self.aflag = 20;
  851.         }
  852.         self.weapon = 1;
  853.         self.netname = "shells";
  854.     }
  855.  
  856.     if (self.spawnflags & WEAPON_SPIKES)
  857.     {
  858.         if (self.spawnflags & WEAPON_BIG)
  859.         {
  860.             precache_model ("maps/b_nail1.bsp");
  861.             setmodel (self, "maps/b_nail1.bsp");
  862.             self.aflag = 40;
  863.         }
  864.         else
  865.         {
  866.             precache_model ("maps/b_nail0.bsp");
  867.             setmodel (self, "maps/b_nail0.bsp");
  868.             self.aflag = 20;
  869.         }
  870.         self.weapon = 2;
  871.         self.netname = "spikes";
  872.     }
  873.  
  874.     if (self.spawnflags & WEAPON_ROCKET)
  875.     {
  876.         if (self.spawnflags & WEAPON_BIG)
  877.         {
  878.             precache_model ("maps/b_rock1.bsp");
  879.             setmodel (self, "maps/b_rock1.bsp");
  880.             self.aflag = 10;
  881.         }
  882.         else
  883.         {
  884.             precache_model ("maps/b_rock0.bsp");
  885.             setmodel (self, "maps/b_rock0.bsp");
  886.             self.aflag = 5;
  887.         }
  888.         self.weapon = 3;
  889.         self.netname = "rockets";
  890.     }
  891.  
  892.     setsize (self, '0 0 0', '32 32 56');
  893.     StartItem ();
  894. };
  895.  
  896.  
  897. /*
  898. ===============================================================================
  899.  
  900. KEYS
  901.  
  902. ===============================================================================
  903. */
  904.  
  905. void() key_touch =
  906. {
  907. local entity    stemp;
  908. local float        best;
  909.  
  910.     if (other.classname != "player")
  911.         return;
  912.     if (other.health <= 0)
  913.         return;
  914.     if (other.items & self.items)
  915.         return;
  916.  
  917.     sprint (other, "You got the ");
  918.     sprint (other, self.netname);
  919.     sprint (other,"\n");
  920.  
  921.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  922.     stuffcmd (other, "bf\n");
  923.     other.items = other.items | self.items;
  924.  
  925.     if (!coop)
  926.     {
  927.         self.solid = SOLID_NOT;
  928.         self.model = string_null;
  929.     }
  930.  
  931.     activator = other;
  932.     SUB_UseTargets();                // fire all targets / killtargets
  933. };
  934.  
  935.  
  936. void() key_setsounds =
  937. {
  938.     if (world.worldtype == 0)
  939.     {
  940.         precache_sound ("misc/medkey.wav");
  941.         self.noise = "misc/medkey.wav";
  942.     }
  943.     if (world.worldtype == 1)
  944.     {
  945.         precache_sound ("misc/runekey.wav");
  946.         self.noise = "misc/runekey.wav";
  947.     }
  948.     if (world.worldtype == 2)
  949.     {
  950.         precache_sound2 ("misc/basekey.wav");
  951.         self.noise = "misc/basekey.wav";
  952.     }
  953. };
  954.  
  955. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  956. SILVER key
  957. In order for keys to work
  958. you MUST set your maps
  959. worldtype to one of the
  960. following:
  961. 0: medieval
  962. 1: metal
  963. 2: base
  964. */
  965.  
  966. void() item_key1 =
  967. {
  968.     if (world.worldtype == 0)
  969.     {
  970.         precache_model ("progs/w_s_key.mdl");
  971.         setmodel (self, "progs/w_s_key.mdl");
  972.         self.netname = "silver key";
  973.     }
  974.     else if (world.worldtype == 1)
  975.     {
  976.         precache_model ("progs/m_s_key.mdl");
  977.         setmodel (self, "progs/m_s_key.mdl");
  978.         self.netname = "silver runekey";
  979.     }
  980.     else if (world.worldtype == 2)
  981.     {
  982.         precache_model2 ("progs/b_s_key.mdl");
  983.         setmodel (self, "progs/b_s_key.mdl");
  984.         self.netname = "silver keycard";
  985.     }
  986.     key_setsounds();
  987.     self.touch = key_touch;
  988.     self.items = IT_KEY1;
  989.     setsize (self, '-16 -16 -24', '16 16 32');
  990.     StartItem ();
  991. };
  992.  
  993. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  994. GOLD key
  995. In order for keys to work
  996. you MUST set your maps
  997. worldtype to one of the
  998. following:
  999. 0: medieval
  1000. 1: metal
  1001. 2: base
  1002. */
  1003.  
  1004. void() item_key2 =
  1005. {
  1006.     if (world.worldtype == 0)
  1007.     {
  1008.         precache_model ("progs/w_g_key.mdl");
  1009.         setmodel (self, "progs/w_g_key.mdl");
  1010.         self.netname = "gold key";
  1011.     }
  1012.     if (world.worldtype == 1)
  1013.     {
  1014.         precache_model ("progs/m_g_key.mdl");
  1015.         setmodel (self, "progs/m_g_key.mdl");
  1016.         self.netname = "gold runekey";
  1017.     }
  1018.     if (world.worldtype == 2)
  1019.     {
  1020.         precache_model2 ("progs/b_g_key.mdl");
  1021.         setmodel (self, "progs/b_g_key.mdl");
  1022.         self.netname = "gold keycard";
  1023.     }
  1024.     key_setsounds();
  1025.     self.touch = key_touch;
  1026.     self.items = IT_KEY2;
  1027.     setsize (self, '-16 -16 -24', '16 16 32');
  1028.     StartItem ();
  1029. };
  1030.  
  1031.  
  1032.  
  1033. /*
  1034. ===============================================================================
  1035.  
  1036. END OF LEVEL RUNES
  1037.  
  1038. ===============================================================================
  1039. */
  1040.  
  1041. void() sigil_touch =
  1042. {
  1043. local entity    stemp;
  1044. local float        best;
  1045.  
  1046.     if (other.classname != "player")
  1047.         return;
  1048.     if (other.health <= 0)
  1049.         return;
  1050.  
  1051.     centerprint (other, "You got the rune!");
  1052.  
  1053.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1054.     stuffcmd (other, "bf\n");
  1055.     self.solid = SOLID_NOT;
  1056.     self.model = string_null;
  1057.     serverflags = serverflags | (self.spawnflags & 15);
  1058.     self.classname = "";        // so rune doors won't find it
  1059.  
  1060.     activator = other;
  1061.     SUB_UseTargets();                // fire all targets / killtargets
  1062. };
  1063.  
  1064.  
  1065. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1066. End of level sigil, pick up to end episode and return to jrstart.
  1067. */
  1068.  
  1069. void() item_sigil =
  1070. {
  1071.     if (!self.spawnflags)
  1072.         objerror ("no spawnflags");
  1073.  
  1074.     precache_sound ("misc/runekey.wav");
  1075.     self.noise = "misc/runekey.wav";
  1076.  
  1077.     if (self.spawnflags & 1)
  1078.     {
  1079.         precache_model ("progs/end1.mdl");
  1080.         setmodel (self, "progs/end1.mdl");
  1081.     }
  1082.     if (self.spawnflags & 2)
  1083.     {
  1084.         precache_model2 ("progs/end2.mdl");
  1085.         setmodel (self, "progs/end2.mdl");
  1086.     }
  1087.     if (self.spawnflags & 4)
  1088.     {
  1089.         precache_model2 ("progs/end3.mdl");
  1090.         setmodel (self, "progs/end3.mdl");
  1091.     }
  1092.     if (self.spawnflags & 8)
  1093.     {
  1094.         precache_model2 ("progs/end4.mdl");
  1095.         setmodel (self, "progs/end4.mdl");
  1096.     }
  1097.  
  1098.     self.touch = sigil_touch;
  1099.     setsize (self, '-16 -16 -24', '16 16 32');
  1100.     StartItem ();
  1101. };
  1102.  
  1103. /*
  1104. ===============================================================================
  1105.  
  1106. POWERUPS
  1107.  
  1108. ===============================================================================
  1109. */
  1110.  
  1111. void() powerup_touch;
  1112.  
  1113.  
  1114. void() powerup_touch =
  1115. {
  1116. local entity    stemp;
  1117. local float        best;
  1118.  
  1119.     if (other.classname != "player")
  1120.         return;
  1121.     if (other.health <= 0)
  1122.         return;
  1123.  
  1124.     sprint (other, "You got the ");
  1125.     sprint (other, self.netname);
  1126.     sprint (other,"\n");
  1127.  
  1128.     if (deathmatch)
  1129.     {
  1130.         self.mdl = self.model;
  1131.  
  1132.         if ((self.classname == "item_artifact_invulnerability") ||
  1133.             (self.classname == "item_artifact_invisibility"))
  1134.             self.nextthink = time + 60*5;
  1135.         else
  1136.             self.nextthink = time + 60;
  1137.  
  1138.         self.think = SUB_regen;
  1139.     }
  1140.  
  1141.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1142.     stuffcmd (other, "bf\n");
  1143.     self.solid = SOLID_NOT;
  1144.     other.items = other.items | self.items;
  1145.     self.model = string_null;
  1146.  
  1147. // do the apropriate action
  1148.     if (self.classname == "item_artifact_envirosuit")
  1149.     {
  1150.         other.rad_time = 1;
  1151.         other.radsuit_finished = time + 30;
  1152.     }
  1153.  
  1154.     if (self.classname == "item_artifact_invulnerability")
  1155.     {
  1156.         other.invincible_time = 1;
  1157.         other.invincible_finished = time + 30;
  1158.     }
  1159.  
  1160.     if (self.classname == "item_artifact_invisibility")
  1161.     {
  1162.         other.invisible_time = 1;
  1163.         other.invisible_finished = time + 30;
  1164.     }
  1165.  
  1166.     if (self.classname == "item_artifact_super_damage")
  1167.     {
  1168.         other.super_time = 1;
  1169.         other.super_damage_finished = time + 30;
  1170.     }
  1171.  
  1172.     activator = other;
  1173.     SUB_UseTargets();                // fire all targets / killtargets
  1174. };
  1175.  
  1176.  
  1177.  
  1178. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1179. Player is invulnerable for 30 seconds
  1180. */
  1181. void() item_artifact_invulnerability =
  1182. {
  1183.     self.touch = powerup_touch;
  1184.  
  1185.     precache_model ("progs/invulner.mdl");
  1186.     precache_sound ("items/protect.wav");
  1187.     precache_sound ("items/protect2.wav");
  1188.     precache_sound ("items/protect3.wav");
  1189.     self.noise = "items/protect.wav";
  1190.     setmodel (self, "progs/invulner.mdl");
  1191.     self.netname = "Pentagram of Protection";
  1192.     self.items = IT_INVULNERABILITY;
  1193.     setsize (self, '-16 -16 -24', '16 16 32');
  1194.     StartItem ();
  1195. };
  1196.  
  1197. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1198. Player takes no damage from water or slime for 30 seconds
  1199. */
  1200. void() item_artifact_envirosuit =
  1201. {
  1202.     self.touch = powerup_touch;
  1203.  
  1204.     precache_model ("progs/suit.mdl");
  1205.     precache_sound ("items/suit.wav");
  1206.     precache_sound ("items/suit2.wav");
  1207.     self.noise = "items/suit.wav";
  1208.     setmodel (self, "progs/suit.mdl");
  1209.     self.netname = "Biosuit";
  1210.     self.items = IT_SUIT;
  1211.     setsize (self, '-16 -16 -24', '16 16 32');
  1212.     StartItem ();
  1213. };
  1214.  
  1215.  
  1216. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1217. Player is invisible for 30 seconds
  1218. */
  1219. void() item_artifact_invisibility =
  1220. {
  1221.     self.touch = powerup_touch;
  1222.  
  1223.     precache_model ("progs/invisibl.mdl");
  1224.     precache_sound ("items/inv1.wav");
  1225.     precache_sound ("items/inv2.wav");
  1226.     precache_sound ("items/inv3.wav");
  1227.     self.noise = "items/inv1.wav";
  1228.     setmodel (self, "progs/invisibl.mdl");
  1229.     self.netname = "Ring of Shadows";
  1230.     self.items = IT_INVISIBILITY;
  1231.     setsize (self, '-16 -16 -24', '16 16 32');
  1232.     StartItem ();
  1233. };
  1234.  
  1235.  
  1236. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1237. The next attack from the player will do 4x damage
  1238. */
  1239. void() item_artifact_super_damage =
  1240. {
  1241.     self.touch = powerup_touch;
  1242.  
  1243.    precache_model ("progs/quaddama.mdl");
  1244.     precache_sound ("items/damage.wav");
  1245.     precache_sound ("items/damage2.wav");
  1246.     precache_sound ("items/damage3.wav");
  1247.     self.noise = "items/damage.wav";
  1248.     setmodel (self, "progs/quaddama.mdl");
  1249.     self.netname = "Quad Damage";
  1250.     self.items = IT_QUAD;
  1251.     setsize (self, '-16 -16 -24', '16 16 32');
  1252.     StartItem ();
  1253. };
  1254.  
  1255.  
  1256.  
  1257. /*
  1258. ===============================================================================
  1259.  
  1260. PLAYER BACKPACKS
  1261.  
  1262. ===============================================================================
  1263. */
  1264.  
  1265. void() BackpackTouch =
  1266. {
  1267.    local string   s;
  1268.    local float best, old, new;
  1269.    local    entity   stemp;
  1270.     local    float    acount;
  1271.  
  1272.     if (other.classname != "player")
  1273.         return;
  1274.     if (other.health <= 0)
  1275.         return;
  1276.  
  1277.    acount = 0;
  1278.    sprint (other, "You get ");
  1279.  
  1280.    if (self.items)
  1281.       {
  1282.       if ((other.items & self.items) == 0)
  1283.       {
  1284.          acount = 1;
  1285.          sprint (other, "the ");
  1286.          sprint (other, self.netname);
  1287.       }
  1288.       }
  1289.  
  1290. // if the player was using his best weapon, change up to the new one if better
  1291.     stemp = self;
  1292.     self = other;
  1293.     best = W_BestWeapon();
  1294.     self = stemp;
  1295.  
  1296. // change weapons
  1297.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1298.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1299.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1300.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1301.  
  1302.    new = self.items;
  1303.     if (!new)
  1304.         new = other.weapon;
  1305.     old = other.items;
  1306.     other.items = other.items | new;
  1307.     
  1308.     bound_other_ammo ();
  1309.  
  1310.    if (self.ammo_shells)
  1311.     {
  1312.         if (acount)
  1313.             sprint(other, ", ");
  1314.         acount = 1;
  1315.         s = ftos(self.ammo_shells);
  1316.         sprint (other, s);
  1317.         sprint (other, " shells");
  1318.     }
  1319.     if (self.ammo_nails)
  1320.     {
  1321.         if (acount)
  1322.             sprint(other, ", ");
  1323.         acount = 1;
  1324.         s = ftos(self.ammo_nails);
  1325.         sprint (other, s);
  1326.         sprint (other, " nails");
  1327.     }
  1328.     if (self.ammo_rockets)
  1329.     {
  1330.         if (acount)
  1331.             sprint(other, ", ");
  1332.         acount = 1;
  1333.         s = ftos(self.ammo_rockets);
  1334.         sprint (other, s);
  1335.         sprint (other, " rockets");
  1336.     }
  1337.     if (self.ammo_cells)
  1338.     {
  1339.         if (acount)
  1340.             sprint(other, ", ");
  1341.         acount = 1;
  1342.         s = ftos(self.ammo_cells);
  1343.         sprint (other, s);
  1344.         sprint (other, " cells");
  1345.     }
  1346.     
  1347.     sprint (other, "\n");
  1348. // backpack touch sound
  1349.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1350.     stuffcmd (other, "bf\n");
  1351.  
  1352. // remove the backpack, change self to the player
  1353.     remove(self);
  1354.     self = other;
  1355.  
  1356. // change to the weapon
  1357.     if (!deathmatch)
  1358.         self.weapon = new;
  1359.     else
  1360.         Deathmatch_Weapon (old, new);
  1361.  
  1362.     W_SetCurrentAmmo ();
  1363. };
  1364.  
  1365. /*
  1366. ===============
  1367. DropBackpack
  1368. ===============
  1369. */
  1370. void() DropBackpack =
  1371. {
  1372.     local entity    item;
  1373.  
  1374.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1375.         return;    // nothing in it
  1376.  
  1377.     item = spawn();
  1378.     item.origin = self.origin - '0 0 24';
  1379.  
  1380.     item.items = self.weapon;
  1381.    if (item.items == IT_AXE)
  1382.         item.netname = "Axe";
  1383. // Grapple:  A new weapon to grab, natch.
  1384.         else if (item.items == IT_MORNINGSTAR)
  1385.                 item.netname = "Morning Star";
  1386. //
  1387.     else if (item.items == IT_SHOTGUN)
  1388.         item.netname = "Shotgun";
  1389.     else if (item.items == IT_SUPER_SHOTGUN)
  1390.         item.netname = "Double-barrelled Shotgun";
  1391.     else if (item.items == IT_NAILGUN)
  1392.         item.netname = "Nailgun";
  1393.     else if (item.items == IT_SUPER_NAILGUN)
  1394.         item.netname = "Super Nailgun";
  1395.     else if (item.items == IT_GRENADE_LAUNCHER)
  1396.         item.netname = "Grenade Launcher";
  1397.     else if (item.items == IT_ROCKET_LAUNCHER)
  1398.         item.netname = "Rocket Launcher";
  1399.     else if (item.items == IT_LIGHTNING)
  1400.         item.netname = "Thunderbolt";
  1401.    else if (item.items == IT_LASER_CANNON)
  1402.       item.netname = "Laser Cannon";
  1403.    else if (item.items == IT_PROXIMITY_GUN)
  1404.       item.netname = "Proximity Gun";
  1405.    else if (item.items == IT_MJOLNIR)
  1406.       item.netname = "Mjolnir";
  1407.    else
  1408.         item.netname = "";
  1409.  
  1410.     item.ammo_shells = self.ammo_shells;
  1411.     item.ammo_nails = self.ammo_nails;
  1412.     item.ammo_rockets = self.ammo_rockets;
  1413.     item.ammo_cells = self.ammo_cells;
  1414.  
  1415.     item.velocity_z = 300;
  1416.     item.velocity_x = -100 + (random() * 200);
  1417.     item.velocity_y = -100 + (random() * 200);
  1418.  
  1419.     item.flags = FL_ITEM;
  1420.     item.solid = SOLID_TRIGGER;
  1421.     item.movetype = MOVETYPE_TOSS;
  1422.     setmodel (item, "progs/backpack.mdl");
  1423.     setsize (item, '-16 -16 0', '16 16 56');
  1424.     item.touch = BackpackTouch;
  1425.  
  1426.     item.nextthink = time + 120;    // remove after 2 minutes
  1427.     item.think = SUB_Remove;
  1428. };
  1429.